package cn.edu.usst.cs.goldfish.booking.meetingroom.web.controller;

import cn.edu.usst.cs.goldfish.booking.meetingroom.mapstruct.AuthMapper;
import cn.edu.usst.cs.goldfish.booking.meetingroom.model.SysUser;
import cn.edu.usst.cs.goldfish.booking.meetingroom.service.UserService;
import cn.edu.usst.cs.goldfish.booking.meetingroom.util.CommonUtil;
import cn.edu.usst.cs.goldfish.booking.meetingroom.web.SessionKeys;
import cn.edu.usst.cs.goldfish.booking.meetingroom.web.dto.auth.CaptchaWrapper;
import cn.edu.usst.cs.goldfish.booking.meetingroom.web.dto.auth.RegisterRequest;
import cn.edu.usst.cs.goldfish.booking.meetingroom.web.dto.auth.UserPreview;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

/**
 * 认证控制器，处理用户身份验证相关请求。
 * 提供登录、注册和验证码发送功能。
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
public class AuthController implements SessionKeys {


    private final UserService userService;
    private final AuthMapper authMapper;
    private final CommonUtil commonUtil;

    public AuthController(
            UserService userService,
            AuthMapper authMapper, CommonUtil commonUtil) {


        this.userService = userService;
        this.authMapper = authMapper;
        this.commonUtil = commonUtil;
    }

    /**
     * 处理用户注册请求。
     *
     * @param registerRequest 包含注册信息的请求对象
     * @return 包含操作结果的响应实体
     */
    @PostMapping("/register/submit")
    public ResponseEntity<String> registerUser(
            @RequestBody RegisterRequest registerRequest,
            HttpSession session
    ) {
        session.setAttribute(SessionKeys.EMAIL, registerRequest.getEmail());
        session.setAttribute(SessionKeys.REGISTRATION_NAME, registerRequest.getUsername());
        long code = userService.sendCaptcha(authMapper.toUserInfoPreview(registerRequest));
        session.setAttribute(SessionKeys.CAPTCHA_CODE, code);
        return ResponseEntity.ok("验证码已发送");
    }

    /**
     * 发送验证码到指定的电子邮件地址。
     *
     * @param email   接收验证码的电子邮件地址
     * @param session 当前会话对象
     * @return 包含操作结果的响应实体
     */
    @PostMapping("/register/verify")
    public ResponseEntity<String> verifyCode(
            @RequestBody CaptchaWrapper wrapper,
            @SessionAttribute(SessionKeys.CAPTCHA_CODE) long captchaCode,
            @SessionAttribute(SessionKeys.EMAIL) String email,
            @SessionAttribute(SessionKeys.REGISTRATION_NAME) String name,
            HttpSession session
    ) {
        commonUtil.ensureEqual(wrapper.getCode(), captchaCode, "验证码错误");

        UserPreview userPreview = UserPreview.builder()
                .username(name)
                .email(email)
                .build();
        userService.createUserFromPreview(userPreview);
        session.invalidate();
        return ResponseEntity.ok("注册成功");
    }

    @PostMapping("/login/submit")
    public ResponseEntity<String> login(
            @RequestParam String identifier,
            HttpSession session
    ) {
        SysUser user = userService.findByCredential(identifier);
        session.setAttribute(SessionKeys.EMAIL, user.getEmail());
        long code = userService.sendCaptcha(authMapper.toUserInfoPreview(user));
        session.setAttribute(SessionKeys.CAPTCHA_CODE, code);
        return ResponseEntity.ok("验证码已发送");
    }

    /**
     * 处理用户登录请求。
     *
     * @param wrapper 包含验证码的包装对象
     * @return 包含JWT令牌的响应实体
     */
    @PostMapping("/login/verify")
    public ResponseEntity<?> login(
            @RequestBody CaptchaWrapper wrapper,
            @SessionAttribute(SessionKeys.CAPTCHA_CODE) long storedCode,
            HttpSession session
    ) {
        commonUtil.ensureEqual(
                storedCode,
                wrapper.getCode(),
                "验证码错误"
        );
        session.setAttribute(SessionKeys.LOGIN_TIME, LocalDateTime.now());
        return ResponseEntity.ok().body("登陆成功");
    }

    /**
     * 检查用户是否登录。
     *
     * @param loginTime 登录时间
     * @return 包含登录状态的响应实体
     */
    @GetMapping("/check-login")
    public ResponseEntity<?> checkLogin(@SessionAttribute(value = SessionKeys.LOGIN_TIME, required = false) Object loginTime) {
        if (loginTime != null) {
            return ResponseEntity.ok().body(java.util.Map.of("loggedIn", true));
        } else {
            return ResponseEntity.status(401).body(java.util.Map.of("loggedIn", false, "message", "未登录"));
        }
    }

    /**
     * 用户登出。
     *
     * @param session HTTP会话对象
     * @return 包含操作结果的响应实体
     */
    @GetMapping("/logout")
    public ResponseEntity<String> logout(HttpSession session) {
        session.invalidate();
        return ResponseEntity.ok("登出成功");
    }

    /**
     * 获取用户信息。
     *
     * @param email 用户邮箱
     * @param loginTime 登录时间
     * @param sessionId 会话ID
     * @return 包含用户信息的响应实体
     */
    @GetMapping("/user-info")
    public ResponseEntity<?> getUserInfo(
            @SessionAttribute(SessionKeys.EMAIL) String email,
            @SessionAttribute(SessionKeys.LOGIN_TIME) Object loginTime,
            @SessionAttribute(value = "sessionId", required = false) String sessionId) {
        
        if (email == null) {
            return ResponseEntity.status(401).body(java.util.Map.of("error", "未登录"));
        }
        
        // 获取用户详细信息
        SysUser user = userService.findByCredential(email);
        
        java.util.Map<String, Object> userInfo = new java.util.HashMap<>();
        userInfo.put("email", email);
        userInfo.put("username", user != null ? user.getUsername() : "");
        userInfo.put("loginTime", loginTime != null ? loginTime.toString() : "");
        userInfo.put("sessionId", sessionId);
        
        return ResponseEntity.ok(userInfo);
    }
}